﻿//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
// Exo² samples - Test
// Copyright (C) 2007-2009 Samuel Lacroix and Raphaël Legouge
//
// Distributed under GNU General Public License
// See the License folder of Exo² for details
//
//
// http://www.codeplex.com/exo2 (eng)
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include "gui.h"


namespace GUI {


tstring CButton::StateSpriteFileName =_T("");
tstring CCheckBox::StateSpriteFileName =_T("");
tstring CSlider::StateSpriteFileName =_T("");
tstring CTextButton::StateSpriteFileName =_T("");


void RegisterComponents()
{
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("button"), CreateButtonCallback);
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("checkbox"), CreateCheckBoxCallback);
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("label"), CreateLabelCallback);
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("horizontalslider"), CreateSliderCallback);
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("textbutton"), CreateTextButtonCallback);
}


Exo2::CMenuComponent* CreateButtonCallback(void* /*pUserData*/)
{
        return new CButton;
}


Exo2::CMenuComponent* CreateCheckBoxCallback(void* /*pUserData*/)
{
        return new CCheckBox;
}


Exo2::CMenuComponent* CreateLabelCallback(void* /*pUserData*/)
{
        return new CLabel;
}


Exo2::CMenuComponent* CreateSliderCallback(void* /*pUserData*/)
{
        return new CSlider;
}


Exo2::CMenuComponent* CreateTextButtonCallback(void* /*pUserData*/)
{
        return new CTextButton;
}


void CButton::LoadStateSprites()
{
    // Fichier qui contient les infos de chargement
        boost::shared_ptr<Exo2::CXMLFile> pStateSpriteFile = Exo2::CResourceManager::Instance().GetResource<Exo2::CXMLFile>(CButton::StateSpriteFileName);
        boost::shared_ptr<Exo2::CXMLSection> pXMLSection = pStateSpriteFile->pRoot->GetChildren(_T("cbutton"))[0];      // Un peu bourrin de ne prendre que le premier
                   
        const Exo2::CXMLSection::TChildren& Children = pXMLSection->GetChildren(_T("texture"));
        for (size_t i = 0; i < Children.size(); ++i)        // Pour chaque texture enregistrée dans le fichier
        {
                const boost::shared_ptr<Exo2::CXMLSection>& pChild = Children[i];
        
                // On charge la texture du sprite
                boost::shared_ptr<Exo2::CTexture> pTexture;
                pTexture = Exo2::CResourceManager::Instance().GetResource<Exo2::CTexture>(pChild->GetAttribute(_T("filename")));        
                
                // On charge le rectangle
                boost::shared_ptr<Exo2::CXMLSection> pRectSection = pChild->GetChildren(_T("rect"))[0];
                long Left   = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("left")));
                long Top    = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("top")));
                long Right  = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("right")));
                long Bottom = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("bottom")));
                boost::shared_ptr<Exo2::CRect> pRect;
                pRect.reset(new Exo2::CRect(Left, Top, Right, Bottom));
                
                // On charge le StateSprite
                boost::shared_ptr<Exo2::CStateSprite<> > pStateSprite;
                pStateSprite.reset(new Exo2::CStateSprite<>(Exo2::SSRM_NONE));
                pStateSprite->SetTexture(pTexture);
                pStateSprite->SetSrcRect(pRect);
                
                // Pour chaque masque
                const Exo2::CXMLSection::TChildren& Masks = pChild->GetChildren(_T("mask"));
                for (size_t j = 0; j < Masks.size(); ++j)
                {
                        boost::shared_ptr<Exo2::CXMLSection> pMaskSection = Masks[j];
                
                        tstring Name = pMaskSection->GetAttribute(_T("name"));
                        D3DXCOLOR Color = Exo2::Utils::StringToValue<D3DXCOLOR>(pMaskSection->GetAttribute(_T("color")));
                        float Fade = Exo2::Utils::StringToValue<float>(pMaskSection->GetAttribute(_T("fade")));
                        pStateSprite->ColorMaskEffects[Name] = Exo2::ColorEffect(Color, Fade);
                }
                
                // Enregistrement
                this->StateSprites.push_back(pStateSprite);
        }
}


void CCheckBox::LoadStateSprites()
{
    // Fichier qui contient les infos de chargement
        boost::shared_ptr<Exo2::CXMLFile> pStateSpriteFile = Exo2::CResourceManager::Instance().GetResource<Exo2::CXMLFile>(CCheckBox::StateSpriteFileName);
        boost::shared_ptr<Exo2::CXMLSection> pXMLSection = pStateSpriteFile->pRoot->GetChildren(_T("ccheckbox"))[0];      // Un peu bourrin de ne prendre que le premier
                   
        const Exo2::CXMLSection::TChildren& Children = pXMLSection->GetChildren(_T("texture"));
        for (size_t i = 0; i < Children.size(); ++i)        // Pour chaque texture enregistrée dans le fichier
        {
                const boost::shared_ptr<Exo2::CXMLSection>& pChild = Children[i];
        
                // On charge la texture du sprite
                boost::shared_ptr<Exo2::CTexture> pTexture;
                pTexture = Exo2::CResourceManager::Instance().GetResource<Exo2::CTexture>(pChild->GetAttribute(_T("filename")));        
                
                // On charge le rectangle
                boost::shared_ptr<Exo2::CXMLSection> pRectSection = pChild->GetChildren(_T("rect"))[0];
                long Left   = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("left")));
                long Top    = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("top")));
                long Right  = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("right")));
                long Bottom = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("bottom")));
                boost::shared_ptr<Exo2::CRect> pRect;
                pRect.reset(new Exo2::CRect(Left, Top, Right, Bottom));
                
                // On charge le StateSprite
                boost::shared_ptr<Exo2::CStateSprite<> > pStateSprite;
                pStateSprite.reset(new Exo2::CStateSprite<>(Exo2::SSRM_NONE));
                pStateSprite->SetTexture(pTexture);
                pStateSprite->SetSrcRect(pRect);
                
                // Pour chaque masque
                const Exo2::CXMLSection::TChildren& Masks = pChild->GetChildren(_T("mask"));
                for (size_t j = 0; j < Masks.size(); ++j)
                {
                        boost::shared_ptr<Exo2::CXMLSection> pMaskSection = Masks[j];
                
                        tstring Name = pMaskSection->GetAttribute(_T("name"));
                        D3DXCOLOR Color = Exo2::Utils::StringToValue<D3DXCOLOR>(pMaskSection->GetAttribute(_T("color")));
                        float Fade = Exo2::Utils::StringToValue<float>(pMaskSection->GetAttribute(_T("fade")));
                        pStateSprite->ColorMaskEffects[Name] = Exo2::ColorEffect(Color, Fade);
                }
                
                // Enregistrement
                this->StateSprites.push_back(pStateSprite);
        }
}


CSlider::CSlider()
{
        this->MinMargin = 4;    // Ne pas mettre ça en dur
        this->MaxMargin = 4;
}


void CSlider::LoadStateSprites()
{    
    // Fichier qui contient les infos de chargement
        boost::shared_ptr<Exo2::CXMLFile> pStateSpriteFile = Exo2::CResourceManager::Instance().GetResource<Exo2::CXMLFile>(CSlider::StateSpriteFileName);
        boost::shared_ptr<Exo2::CXMLSection> pXMLSection = pStateSpriteFile->pRoot->GetChildren(_T("cslider"))[0];      // Un peu bourrin de ne prendre que le premier
                   
        const Exo2::CXMLSection::TChildren& Children = pXMLSection->GetChildren(_T("texture"));
        for (size_t i = 0; i < Children.size(); ++i)        // Pour chaque texture enregistrée dans le fichier
        {
                const boost::shared_ptr<Exo2::CXMLSection>& pChild = Children[i];
        
                // On charge la texture du sprite
                boost::shared_ptr<Exo2::CTexture> pTexture;
                pTexture = Exo2::CResourceManager::Instance().GetResource<Exo2::CTexture>(pChild->GetAttribute(_T("filename")));        
                
                // On charge le rectangle
                boost::shared_ptr<Exo2::CXMLSection> pRectSection = pChild->GetChildren(_T("rect"))[0];
                long Left   = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("left")));
                long Top    = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("top")));
                long Right  = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("right")));
                long Bottom = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("bottom")));
                boost::shared_ptr<Exo2::CRect> pRect;
                pRect.reset(new Exo2::CRect(Left, Top, Right, Bottom));
                
                // On regarde quel type de state sprite c'est
                boost::shared_ptr<Exo2::CMenuHorizontalSlider::CSliderSprite> pSliderSprite;
                Exo2::CMenuHorizontalSlider::SLIDER_SPRITE_USAGE Usage = Exo2::CMenuHorizontalSlider::SSU_NONE;
                tstring SpriteUsage = pChild->GetAttribute(_T("usage"));
                if (SpriteUsage == _T("thumb"))
                    Usage = Exo2::CMenuHorizontalSlider::SSU_THUMB;
                else if (SpriteUsage == _T("left"))
                    Usage = Exo2::CMenuHorizontalSlider::SSU_LEFT;
                else if (SpriteUsage == _T("right"))
                    Usage = Exo2::CMenuHorizontalSlider::SSU_RIGHT;
                
                pSliderSprite.reset(new Exo2::CMenuHorizontalSlider::CSliderSprite(Usage, Exo2::SSRM_NONE));

                pSliderSprite->SetTexture(pTexture);
                pSliderSprite->SetSrcRect(pRect);
                
                // Pour chaque masque
                const Exo2::CXMLSection::TChildren& Masks = pChild->GetChildren(_T("mask"));
                for (size_t j = 0; j < Masks.size(); ++j)
                {
                        boost::shared_ptr<Exo2::CXMLSection> pMaskSection = Masks[j];
                
                        tstring Name = pMaskSection->GetAttribute(_T("name"));
                        D3DXCOLOR Color = Exo2::Utils::StringToValue<D3DXCOLOR>(pMaskSection->GetAttribute(_T("color")));
                        float Fade = Exo2::Utils::StringToValue<float>(pMaskSection->GetAttribute(_T("fade")));
                        pSliderSprite->ColorMaskEffects[Name] = Exo2::ColorEffect(Color, Fade);
                }
                
                // Enregistrement
                this->StateSprites.push_back(pSliderSprite);
        }
}


void CTextButton::LoadStateSprites()
{
    // Fichier qui contient les infos de chargement
        boost::shared_ptr<Exo2::CXMLFile> pStateSpriteFile = Exo2::CResourceManager::Instance().GetResource<Exo2::CXMLFile>(CTextButton::StateSpriteFileName);
        boost::shared_ptr<Exo2::CXMLSection> pXMLSection = pStateSpriteFile->pRoot->GetChildren(_T("ctextbutton"))[0];      // Un peu bourrin de ne prendre que le premier
                   
        const Exo2::CXMLSection::TChildren& Children = pXMLSection->GetChildren(_T("texture"));
        for (size_t i = 0; i < Children.size(); ++i)        // Pour chaque texture enregistrée dans le fichier
        {
                const boost::shared_ptr<Exo2::CXMLSection>& pChild = Children[i];
        
                // On charge la texture du sprite
                boost::shared_ptr<Exo2::CTexture> pTexture;
                pTexture = Exo2::CResourceManager::Instance().GetResource<Exo2::CTexture>(pChild->GetAttribute(_T("filename")));        
                
                // On charge le rectangle
                boost::shared_ptr<Exo2::CXMLSection> pRectSection = pChild->GetChildren(_T("rect"))[0];
                long Left   = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("left")));
                long Top    = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("top")));
                long Right  = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("right")));
                long Bottom = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("bottom")));
                boost::shared_ptr<Exo2::CRect> pRect;
                pRect.reset(new Exo2::CRect(Left, Top, Right, Bottom));
                
                // On charge le StateSprite
                boost::shared_ptr<Exo2::CStateSprite<> > pStateSprite;
                pStateSprite.reset(new Exo2::CStateSprite<>(Exo2::SSRM_NONE));
                pStateSprite->SetTexture(pTexture);
                pStateSprite->SetSrcRect(pRect);
                
                // Pour chaque masque
                const Exo2::CXMLSection::TChildren& Masks = pChild->GetChildren(_T("mask"));
                for (size_t j = 0; j < Masks.size(); ++j)
                {
                        boost::shared_ptr<Exo2::CXMLSection> pMaskSection = Masks[j];
                
                        tstring Name = pMaskSection->GetAttribute(_T("name"));
                        D3DXCOLOR Color = Exo2::Utils::StringToValue<D3DXCOLOR>(pMaskSection->GetAttribute(_T("color")));
                        float Fade = Exo2::Utils::StringToValue<float>(pMaskSection->GetAttribute(_T("fade")));
                        pStateSprite->ColorMaskEffects[Name] = Exo2::ColorEffect(Color, Fade);
                }
                
                // Enregistrement
                this->StateSprites.push_back(pStateSprite);
        }
}


void ResetTest1()
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
#define RESET_LABEL(x) if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent((x), _T("main")))) pLabel->Text->Set(_T(" "))
        
        RESET_LABEL(_T("labelmainclick"));
        RESET_LABEL(_T("labelmaindblclick"));
        RESET_LABEL(_T("labelmainmouseenter"));
        RESET_LABEL(_T("labelmainmouseleave"));
        RESET_LABEL(_T("labelmainmouseup"));
        RESET_LABEL(_T("labelmainmousedown"));
        RESET_LABEL(_T("labelmainmousemove"));
}


void ResetTest2()
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        
        RESET_LABEL(_T("labelmaincheckbox"));
}


void ResetTest3()
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        
        RESET_LABEL(_T("labelmainonchangetest3"));

#undef RESET_LABEL
}


void OnClickGoToSubMenu(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        GUI::CMenuManager::Instance().Enter(_T("submenu"));
}


void OnClickBack(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        GUI::CMenuManager::Instance().Back();
}


void OnClickResetTest(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        ResetTest1();
        ResetTest2();
        ResetTest3();
}


void OnClickTest1(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelmainclick"), _T("main"))))
        {
                pLabel->Text->Set(_T("Click"));
        }
}


void OnDblClickTest1(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelmaindblclick"), _T("main"))))
        {
                pLabel->Text->Set(_T("DblClick"));
        }        
}


void OnMouseEnterTest1(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelmainmouseenter"), _T("main"))))
        {
                pLabel->Text->Set(_T("Enter"));
        } 
}


void OnMouseLeaveTest1(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelmainmouseleave"), _T("main"))))
        {
                pLabel->Text->Set(_T("Leave"));
        } 
}


void OnMouseUpTest1(Exo2::CMenuComponent* /*pSender*/, Exo2::MENU_MOUSE_BUTTON mb, long X, long Y, void* /*pUserData*/)
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelmainmouseup"), _T("main"))))
        {
                tostringstream oss;
                switch (mb)
                {
                    case Exo2::MMB_LEFT:
                        oss << _T("L ");
                        break;
                    case Exo2::MMB_MIDDLE:
                        oss << _T("M ");
                        break;
                    case Exo2::MMB_RIGHT:
                        oss << _T("R ");
                        break;
                    case Exo2::MMB_WHEELDOWN:
                        oss << _T("WD ");
                        break;
                    case Exo2::MMB_WHEELUP:
                        oss << _T("WU ");
                        break;
                    default:
                        oss << _T("error ");
                        pLabel->Text->Set(oss.str());
                        return;
                }
                oss << _T("Up(") << X << _T(",") << Y << _T(")");
                pLabel->Text->Set(oss.str());
        } 
}


void OnMouseDownTest1(Exo2::CMenuComponent* /*pSender*/, Exo2::MENU_MOUSE_BUTTON mb, long X, long Y, void* /*pUserData*/)
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelmainmousedown"), _T("main"))))
        {
                tostringstream oss;
                switch (mb)
                {
                    case Exo2::MMB_LEFT:
                        oss << _T("L ");
                        break;
                    case Exo2::MMB_MIDDLE:
                        oss << _T("M ");
                        break;
                    case Exo2::MMB_RIGHT:
                        oss << _T("R ");
                        break;
                    case Exo2::MMB_WHEELDOWN:
                        oss << _T("WD ");
                        break;
                    case Exo2::MMB_WHEELUP:
                        oss << _T("WU ");
                        break;
                    default:
                        oss << _T("error ");
                        pLabel->Text->Set(oss.str());
                        return;
                }
                oss << _T("Down(") << X << _T(",") << Y << _T(")");
                pLabel->Text->Set(oss.str());
        } 
}


void OnMouseMoveTest1(Exo2::CMenuComponent* /*pSender*/, long X, long Y, void* /*pUserData*/)
{
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelmainmousemove"), _T("main"))))
        {
                tostringstream oss;
                oss << _T("Move(") << X << _T(",") << Y << _T(")");
                pLabel->Text->Set(oss.str());
        } 
}


void OnClickTest2(Exo2::CMenuComponent* pSender, void* /*pUserData*/)
{
        Exo2::CMenuCheckBox* pCheckBox = NULL;
        pCheckBox = static_cast<Exo2::CMenuCheckBox*>(pSender);
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelmaincheckbox"), _T("main"))))
        {
                tostringstream oss;
                if (pCheckBox->Checked->Get())
                    oss << _T("Checked");
                else
                    oss << _T("Unchecked");
                pLabel->Text->Set(oss.str());
        }
}


void OnChangeTest3(Exo2::CMenuComponent* pSender, void* /*pUserData*/)
{
        Exo2::CMenuHorizontalSlider* pSlider = NULL;
        pSlider = static_cast<Exo2::CMenuHorizontalSlider*>(pSender);
        boost::shared_ptr<Exo2::CMenuLabel> pLabel;
        if (pLabel = boost::dynamic_pointer_cast<Exo2::CMenuLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelmainonchangetest3"), _T("main"))))
        {
                tostringstream oss;
                oss << pSlider->Min->Get() << _T("/") << pSlider->Pos->Get() << _T("/") << pSlider->Max->Get();
                pLabel->Text->Set(oss.str());
        }
}


}